package com.sinosoft.dsp.platform.manager;

import java.io.Serializable;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.NoneScoped;

import com.sinosoft.builder.templates.view.LayoutType;
import com.sinosoft.builder.templates.view.SceneType;
import com.sinosoft.builder.templates.view.LayoutType.AnyAttributes;
import com.sinosoft.dsp.platform.components.IViewBean;
import com.sinosoft.dsp.platform.components.system.ITabBean;
import com.sinosoft.dsp.platform.components.system.IWindowBean;
import com.sinosoft.dsp.platform.components.system.TabBean;
import com.sinosoft.dsp.platform.components.system.WindowBean;
import com.sinosoft.dsp.platform.components.system.WindowSetViewBean;
import com.sinosoft.dsp.platform.exception.SinoPlatformException;
import com.sinosoft.dsp.platform.services.PlatformViewService;
import com.sinosoft.dsp.platform.utils.SinoManagedBean;
import com.sinosoft.dsp.system.core.exception.SinoXMLException;
import com.sinosoft.dsp.system.core.log.Log;
import com.sinosoft.dsp.system.to.IGenericTO;
import com.sinosoft.dsp.system.utils.Const;

/**
 * 该类是应用程序控制器，其中包含了页面框架的全部信息。 通过ViewBean来管理页面视图，ViewBean可以关联Layout。
 * 如果Layout是单例的，在本Session内部只保留一个ViewBean对象。
 * 注意：layout在页面不能直接被传递，而是要通过viewBeanId来获得ViewBean，然后通过ViewBean来获得Layout。
 * 
 * @since 1.0 2010-3-24
 * @author 潘巍（Peter Pan）
 * 
 */
@ManagedBean(name = "applicationController")
@NoneScoped
public class ApplicationController implements Serializable {

	private static final long serialVersionUID = -4311818917588054356L;

	private static final Log log = Log.getLog(ApplicationController.class
			.getName());

	@ManagedProperty(value = "#{platformViewService}")
	private PlatformViewService view;

	public static final String BASE_CONTENT_PATH = "includes/portal/";

	// 页面非单例视图的Id前缀
	public static final String VIEW_PREFIX = "view_";

	// 页面非单例视图的Id的自动排序号
	private int viewAutoIndex = 0;

	/**
	 * Portal页面的根ViewBean的Id
	 */
	private String rootViewBeanId = Const.LAYOUT_PORTAL_ID;

	private String applicationId = Const.DEFAULT_APPLICATION_ID;

	/**
	 * 遮蔽蒙板文字
	 */
	private String maskMessage = Const.PORTAL_MASK_LABEL;

	public String getRootViewBeanId() {
		return rootViewBeanId;
	}

	public void setRootViewBeanId(String rootViewBeanId) {
		this.rootViewBeanId = rootViewBeanId;
	}

	public String getApplicationId() {
		return applicationId;
	}

	public void setApplicationId(String applicationId) {
		this.applicationId = applicationId;
	}

	public void resetMaskMessage() {
		this.maskMessage = Const.PORTAL_MASK_LABEL;
	}

	public String getMaskMessage() {
		return maskMessage;
	}

	public void setMaskMessage(String maskMessage) {
		this.maskMessage = maskMessage;
	}

	/**
	 * 通过资源文件名得到绝对路径
	 * 
	 * @param fileName
	 * @return
	 */

	public String getResourceAbsolutePath(String fileName) {
		return BASE_CONTENT_PATH + fileName;
	}

	public String getResourceAbsolutePath(LayoutType l) {
		return getResourceAbsolutePath(l.getSrc());
	}

	/**
	 * 初始化通过用户Portal
	 */
	public void resetPortal() {
		// TODO
	}

	/**
	 * 重新设置Window内容
	 * 
	 * @param sceneId
	 * @param layoutId
	 * @param parentId
	 * @throws SinoPlatformException
	 */
	public IWindowBean popupWindow(String sceneId, String layoutId,
			IGenericTO tos, String parentId) throws SinoPlatformException {
		return popupWindow(sceneId, layoutId, null, tos, parentId);
	}

	/**
	 * 
	 * @param sceneId
	 * @param layoutId
	 * @param params
	 * @param parentId
	 * @throws SinoPlatformException
	 */
	public IWindowBean popupWindow(String sceneId, String layoutId,
			Map<String, String> params, IGenericTO tos, String parentId)
			throws SinoPlatformException {
		try {
			WindowSetViewBean ws = SinoManagedBean
					.findBean("windowSetViewBean");

			LayoutType targetLayout = view.getLayout(sceneId, layoutId);

			// 1.创建一个Window内容
			IViewBean content = view.createFullViewBean(sceneId, layoutId, tos,
					null);

			// 2.创建一个Window
			IWindowBean windowViewBean = (IWindowBean) view.createFullViewBean(
					"window_content", "window-default", tos, content.getId()
							+ "_win");
			windowViewBean.setContent(content);

			// 3.设置窗口属性
			for (String attributeLabel : WindowBean.ATTRIBUTE) {
				String param = getLayoutAttribute(attributeLabel, params,
						targetLayout);
				if (param != null)
					windowViewBean.putAttr(attributeLabel, param);
			}

			// 4.插入到WindowSetBean集合中
			ws.addView(windowViewBean);
			return windowViewBean;
		} catch (SinoXMLException e) {
			log.error("获得Layout出现XML解析错误");
		}
		return null;
	}

	private String getLayoutAttribute(String key, Map<String, String> params,
			LayoutType layout) {
		return (String) getLayoutAttribute(key, params, layout, "");
	}

	private Object getLayoutAttribute(String key, Map<String, String> params,
			LayoutType layout, String type) {
		String p = params.get(key);
		if (p != null) {
			if ("integer".equals(type)) {
				return Integer.valueOf(p);
			} else if ("boolean".equals(type)) {
				return Boolean.valueOf(p);
			} else {
				return p;
			}
		}

		for (AnyAttributes aa : layout.getAnyAttributes()) {
			if (key.equalsIgnoreCase(aa.getKey())) {
				if ("integer".equals(type)) {
					return Integer.valueOf(aa.getValue());
				} else if ("boolean".equals(type)) {
					return Boolean.valueOf(aa.getValue());
				} else {
					return aa.getValue();
				}
			}
		}
		return null;
	}

	/**
	 * 创建一个新的Tab页面，同时程序刷新“main-tabSet” ViewBean中调用如下： IApplicationController ac
	 * = (IApplicationController) Component<br>
	 * .getInstance("applicationController");<br>
	 * ac.createTab(...);<br>
	 * 
	 * 相关参数可以在Tab内容的Layout中配置，如：image16和closable， 同时设置其displayName属性也同样能起作用
	 * 
	 * @param sceneId
	 * @param layoutId
	 * @param tos
	 * @param parentId
	 * @throws SinoPlatformException
	 */
	public ITabBean createTab(String sceneId, String layoutId, IGenericTO tos)
			throws SinoPlatformException {
		return createTab(null, null, null, sceneId, layoutId, tos);
	}

	/**
	 * 创建一个新的Tab页面，同时程序刷新“main-tabSet”
	 * 
	 * @param displayName
	 * @param image16
	 * @param closable
	 * @param sceneId
	 * @param layoutId
	 * @param tos
	 * @param parentId
	 * @throws SinoPlatformException
	 */
	public ITabBean createTab(String displayName, String image16,
			Boolean closable, String sceneId, String layoutId, IGenericTO tos)
			throws SinoPlatformException {

		try {
			// 1.获得一个内容对象
			SceneType contentScene = view.getSceneById(sceneId);
			LayoutType contentLayout = view.getLayout(sceneId, layoutId);
			if (contentScene == null) {
				throw new SinoPlatformException("无法通过ID获得场景，请检查ID是否正确，ID："
						+ sceneId);
			}
			if (contentLayout == null) {
				throw new SinoPlatformException("无法通过ID获得布局，请检查ID是否正确，ID："
						+ layoutId);
			}

			// 2.创建一个ViewBean对象
			IViewBean content = view.createFullViewBean(contentScene,
					contentLayout, tos, null);
			// 3.创建一个TabBean
			ITabBean tb = (ITabBean) view.createFullViewBean("mainContent",
					"tab-default", tos, content.getId() + "_tab");
			if (!Const.isEmpty(displayName)) {
				tb.putAttr(TabBean.ATTRIBUTE_LABEL, displayName);
			}
			if (!Const.isEmpty(image16)) {
				tb.putAttr(TabBean.ATTRIBUTE_IMAGE16, image16);
			}
			if (closable != null) {
				tb.putAttr(TabBean.ATTRIBUTE_CLOSABLE, closable.toString());
			}
			tb.setContent(content);

			return tb;
		} catch (SinoXMLException e) {
			log.error("创建Tab出现错误");
			throw new SinoPlatformException(e);
		}
	}

	public ITabBean createTabBySrc(String displayName, String image16,
			Boolean closable, String src, IGenericTO tos)
			throws SinoPlatformException {
		ITabBean tb = (ITabBean) view.createFullViewBean("mainContent",
				"tab-default", tos, null);
		if (!Const.isEmpty(displayName)) {
			tb.putAttr(TabBean.ATTRIBUTE_LABEL, displayName);
		}
		if (!Const.isEmpty(image16)) {
			tb.putAttr(TabBean.ATTRIBUTE_IMAGE16, image16);
		}
		if (closable != null) {
			tb.putAttr(TabBean.ATTRIBUTE_CLOSABLE, closable.toString());
		}
		if (!Const.isEmpty(src)) {
			tb.putAttr(TabBean.ATTRIBUTE_SRC, src);
		}
		return tb;
	}

	public PlatformViewService getView() {
		return view;
	}

	public void setView(PlatformViewService view) {
		this.view = view;
	}

}
